#include <iostream>
#include <string>
#include <sstream>
#include "binarytree.h"
#define MU_NOCOLOR
#include "miniunit.h"

using namespace std;

auto pa = new BiTNode<char>{'a', nullptr, nullptr};
auto pb = new BiTNode<char>{'b', nullptr, nullptr};
auto pc = new BiTNode<char>{'c', nullptr, pb};
auto pd = new BiTNode<char>{'d', nullptr, nullptr};
auto pe = new BiTNode<char>{'e', pc, pd};
auto pf = new BiTNode<char>{'f', pa, pe};

auto T = pf;


// Check functions needed
using ::Depth;       // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::Destroy;     // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::FindMaxBST;  // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::FindMinBST;  // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::Inorder;     // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::InsertBST;   // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::LeafCount;   // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::NodeCount;   // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::Postorder;   // 错误: 找不到该函数, 请检查代码, 注意大小写
using ::Preorder;    // 错误: 找不到该函数, 请检查代码, 注意大小写

int test_traverse()
{
	ostringstream r;
	auto visit = [&](char c) { r << c; };
	
	r.str("");
	Preorder(T, visit);
	mu_assert(r.str() == "faecbd", "Preorder 错误: '%s'", r.str().c_str());

	r.str("");
	Inorder(T, visit);
	mu_assert(r.str() == "afcbed", "Inorder 错误: '%s'", r.str().c_str());

	r.str("");
	Postorder(T, visit);
	mu_assert(r.str() == "abcdef", "Postorder 错误: '%s'", r.str().c_str());

	return 0;
}

int test_node_count()
{
	mu_assert(6 == NodeCount(T), "NodeCount 错误: %d", NodeCount(T));
	return 0;
}

int test_leaf_count()
{
	mu_assert(3 == LeafCount(T), "LeafCount 错误: %d", LeafCount(T));
	return 0;
}

int test_depth()
{
	mu_assert(4 == Depth(T), "Depth 错误: %d", Depth(T));
	return 0;
}

int test_destroy()
{
	Destroy(T);
	mu_assert(T == nullptr, "Destroy 错误");
	return 0;
}

int test_bst_algo()
{
	int a[] = {53, 45, 12, 24, 90, 45, 80};
	BiTree<int> T = nullptr;
	for (auto x : a)
		InsertBST(T, x);
	mu_assert(T->data == 53);
	mu_assert(FindMinBST(T)->data == 12);
	mu_assert(FindMaxBST(T)->data == 90);
	Destroy(T);

	return 0;
}


int main()
{
    mu_run_test(test_traverse);
    mu_run_test(test_node_count);
    mu_run_test(test_leaf_count);
    mu_run_test(test_depth);
    mu_run_test(test_destroy);
    mu_run_test(test_bst_algo);

    mu_test_results();

    return 0;
}
